import api, { getResponseCount } from '@/store/api';
import i18n from '@/i18n';
const { t } = i18n.global as any;

export const useUserManagementStore = defineStore('userManagement', () => {
  const allUsers = ref([]);
  const accountRoles = ref([]);
  const accountLockoutDuration = ref(null);
  const accountLockoutThreshold = ref(null);
  const accountMinPasswordLength = ref(0);
  const accountMaxPasswordLength = ref(0);

  const accountSettings = computed(() => {
    return {
      lockoutDuration: accountLockoutDuration.value,
      lockoutThreshold: accountLockoutThreshold.value,
    };
  });
  const accountPasswordRequirements = computed(() => {
    return {
      minLength: accountMinPasswordLength.value,
      maxLength: accountMaxPasswordLength.value,
    };
  });

  const setUsers = (Users: any) => {
    allUsers.value = Users;
  };
  const setAccountRoles = (Roles: any) => {
    accountRoles.value = Roles;
  };
  const setLockoutDuration = (lockoutDuration: any) => {
    accountLockoutDuration.value = lockoutDuration;
  };
  const setLockoutThreshold = (lockoutThreshold: any) => {
    accountLockoutThreshold.value = lockoutThreshold;
  };
  const setAccountMinPasswordLength = (minPasswordLength: any) => {
    accountMinPasswordLength.value = minPasswordLength;
  };
  const setAccountMaxPasswordLength = (maxPasswordLength: any) => {
    accountMaxPasswordLength.value = maxPasswordLength;
  };
  const getUsers = async () => {
    return await api
      .get('/redfish/v1/AccountService/Accounts')
      .then((response) =>
        response.data.Members.map(
          (user: { [x: string]: any }) => user['@odata.id'],
        ),
      )
      .then((userIds) => api.all(userIds.map((user: string) => api.get(user))))
      .then((users: any[]) => {
        const userData = users.map((user) => user.data);
        setUsers(userData);
      })
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorLoadUsers');
        throw new Error(message as string);
      });
  };
  const getAccountSettings = async () => {
    return await api
      .get('/redfish/v1/AccountService')
      .then(({ data }) => {
        setLockoutDuration(data.AccountLockoutDuration);
        setLockoutThreshold(data.AccountLockoutThreshold);
        setAccountMinPasswordLength(data.MinPasswordLength);
        setAccountMaxPasswordLength(data.MaxPasswordLength);
      })
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorLoadAccountSettings');
        throw new Error(message as string);
      });
  };
  const getAccountRoles = async () => {
    return await api
      .get('/redfish/v1/AccountService/Roles')
      .then(({ data: { Members = [] } = {} }) => {
        const roles = Members.map((role: { [x: string]: string }) => {
          return role['@odata.id'].split('/').pop();
        });
        setAccountRoles(roles);
      })
      .catch((error) => console.log(error));
  };
  const changePassword = async ({
    username,
    password,
  }: {
    username: string;
    password: string;
  }) => {
    return await api
      .patch(`/redfish/v1/AccountService/Accounts/${username}`, {
        Password: password,
      })
      .then(() => getUsers())
      .then(() =>
        t('pageUserManagement.toast.successUpdateUser', {
          username: username,
        }),
      )
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorUpdateUser', {
          username: username,
        });
        throw new Error(message as string);
      });
  };
  const createUser = async ({
    username,
    password,
    privilege,
    status,
    maxdaysexpired,
  }: {
    username: string;
    password: string;
    privilege: string;
    status: string;
    maxdaysexpired: number;
  }) => {
    const data = {
      UserName: username,
      Password: password,
      RoleId: privilege,
      Enabled: status,
      PasswordExpirationDays: +maxdaysexpired,
    };
    return await api
      .post('/redfish/v1/AccountService/Accounts', data, undefined)
      .then(() => getUsers())
      .then(() =>
        t('pageUserManagement.toast.successCreateUser', {
          username,
        }),
      )
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorCreateUser', {
          username,
        });
        throw new Error(message as string);
      });
  };
  const updateUser = async ({
    originalUsername,
    username,
    password,
    privilege,
    status,
    locked,
    maxdaysexpired,
  }: {
    originalUsername?: string | null;
    username?: string | null;
    password?: string | null;
    privilege?: string | null;
    status?: string | null;
    locked?: string | null;
    maxdaysexpired?: string | null;
  }) => {
    const data: { [index: string]: any } = {};
    if (username) data.UserName = username;
    if (password) data.Password = password;
    if (privilege) {
      if (privilege != 'Administrator') {
        // Count administrators.
        let adminCount = 0;
        let curUser: { [index: string]: string } = {};
        allUsers.value.forEach((item: { RoleId: string; UserName: string }) => {
          if (item.RoleId == 'Administrator') {
            adminCount++;
          }
          if (item.UserName == originalUsername) {
            curUser = item;
            return;
          }
        });
        // Prevent make adminCount < 1
        if (adminCount <= 1) {
          if (curUser.RoleId == 'Administrator') {
            const message = t('pageUserManagement.toast.errorUpdateUser', {
              username: originalUsername,
            });
            throw new Error(message as string);
          }
        }
      }
      data.RoleId = privilege;
    }
    if (status !== undefined) data.Enabled = status;
    if (locked !== undefined) data.Locked = locked;
    if (maxdaysexpired) data.PasswordExpirationDays = +maxdaysexpired;
    return await api
      .patch(`/redfish/v1/AccountService/Accounts/${originalUsername}`, data)
      .then(() => getUsers())
      .then(() =>
        t('pageUserManagement.toast.successUpdateUser', {
          username: originalUsername,
        }),
      )
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorUpdateUser', {
          username: originalUsername,
        });
        throw new Error(message as string);
      });
  };
  const deleteUser = async (username: any) => {
    return await api
      .delete(`/redfish/v1/AccountService/Accounts/${username}`, undefined)
      .then(() => getUsers())
      .then(() =>
        t('pageUserManagement.toast.successDeleteUser', {
          username,
        }),
      )
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorDeleteUser', {
          username,
        });
        throw new Error(message as string);
      });
  };
  const deleteUsers = async (users: { username: any }[]) => {
    const promises = users.map(({ username }) => {
      return api
        .delete(`/redfish/v1/AccountService/Accounts/${username}`, undefined)
        .catch((error) => {
          console.log(error);
          return error;
        });
    });
    return await api
      .all(promises)
      .then((response) => {
        getUsers();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];

          if (successCount) {
            const message = t(
              'pageUserManagement.toast.successBatchDelete',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }

          if (errorCount) {
            const message = t(
              'pageUserManagement.toast.errorBatchDelete',
              errorCount,
            );
            toastMessages.push({ type: 'error', message });
          }

          return toastMessages;
        }),
      );
  };
  const enableUsers = async (users: { username: any }[]) => {
    const data = {
      Enabled: true,
    };
    const promises = users.map(({ username }) => {
      return api
        .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
        .catch((error) => {
          console.log(error);
          return error;
        });
    });
    return await api
      .all(promises)
      .then((response) => {
        getUsers();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];

          if (successCount) {
            const message = t(
              'pageUserManagement.toast.successBatchEnable',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }

          if (errorCount) {
            const message = t(
              'pageUserManagement.toast.errorBatchEnable',
              errorCount,
            );
            toastMessages.push({ type: 'error', message });
          }

          return toastMessages;
        }),
      );
  };
  const disableUsers = async (users: { username: any }[]) => {
    const data = {
      Enabled: false,
    };
    const promises = users.map(({ username }) => {
      return api
        .patch(`/redfish/v1/AccountService/Accounts/${username}`, data)
        .catch((error) => {
          console.log(error);
          return error;
        });
    });
    return await api
      .all(promises)
      .then((response) => {
        getUsers();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];

          if (successCount) {
            const message = t(
              'pageUserManagement.toast.successBatchDisable',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }

          if (errorCount) {
            const message = t(
              'pageUserManagement.toast.errorBatchDisable',
              errorCount,
            );
            toastMessages.push({ type: 'error', message });
          }

          return toastMessages;
        }),
      );
  };
  const saveAccountSettings = async ({
    lockoutThreshold,
    lockoutDuration,
  }: any) => {
    const data: { [index: string]: any } = {};
    if (lockoutThreshold !== undefined) {
      data.AccountLockoutThreshold = lockoutThreshold;
    }
    if (lockoutDuration !== undefined) {
      data.AccountLockoutDuration = lockoutDuration;
    }

    return await api
      .patch('/redfish/v1/AccountService', data)
      //GET new settings to update view
      .then(() => getAccountSettings())
      .then(() => t('pageUserManagement.toast.successSaveSettings'))
      .catch((error) => {
        console.log(error);
        const message = t('pageUserManagement.toast.errorSaveSettings');
        throw new Error(message as string);
      });
  };
  return {
    allUsers,
    accountRoles,
    accountLockoutDuration,
    accountLockoutThreshold,
    accountMinPasswordLength,
    accountMaxPasswordLength,
    accountSettings,
    accountPasswordRequirements,
    setUsers,
    setAccountRoles,
    setLockoutDuration,
    setLockoutThreshold,
    setAccountMinPasswordLength,
    setAccountMaxPasswordLength,
    getUsers,
    getAccountSettings,
    getAccountRoles,
    changePassword,
    createUser,
    updateUser,
    deleteUser,
    deleteUsers,
    enableUsers,
    disableUsers,
    saveAccountSettings,
  };
});
